package com.yss.common.core.utils.easyexecl;

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.yss.common.core.annotation.EasyExcel;
import com.yss.common.core.utils.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class StringConverter implements Converter<String> {
    @Override
    public Class supportJavaTypeKey() {
        //指定状态码类型
        return String.class;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        //指定需要获取的参数类型
        return CellDataTypeEnum.STRING;
    }

    @Override
    public WriteCellData<?> convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        //value:状态码  contentProperty：字段属性  globalConfiguration：全局配置
        //获取字段属性中的注解
        Field field = contentProperty.getField();
        EasyExcel easyExcel = field.getAnnotation(EasyExcel.class);
        //获取注解中的枚举信息
        Class<? extends Enum> type = easyExcel.type();
        if (!type.getName().endsWith("None")) {
            //获取枚举类的方法名 “getEnum”就是自己编写的函数，Integer.class 指定入参类型
            Method codeOf = type.getMethod("getEnum", String.class);
            //反射执行方法，此方法得到的是一个枚举实例（具体得到什么，结合自身项目）
            Object invoke = codeOf.invoke(type, value);
            //枚举实例调用getEnumDesc方法，得到name的值
            Method getName = invoke.getClass().getMethod("getDesc");
            String name = String.valueOf(getName.invoke(invoke));
            //将转换的值进行返回
            return new WriteCellData(name);
        } else if (StringUtils.isNotEmpty(easyExcel.readConverterExp())) {  // 解析配置的字符串
            return new WriteCellData<>(convertByExp(value, easyExcel.readConverterExp(), easyExcel.separator()));
        }
        return new WriteCellData<>("");
    }


    /**
     * 解析导出值 0=男,1=女,2=未知
     *
     * @param propertyValue 参数值
     * @param converterExp  翻译注解
     * @param separator     分隔符
     * @return 解析后值
     */
    public static String convertByExp(String propertyValue, String converterExp, String separator) {
        StringBuilder propertyString = new StringBuilder();
        String[] convertSource = converterExp.split(",");
        for (String item : convertSource) {
            String[] itemArray = item.split("=");
            if (StringUtils.containsAny(propertyValue, separator)) {
                for (String value : propertyValue.split(separator)) {
                    if (itemArray[0].equals(value)) {
                        propertyString.append(itemArray[1] + separator);
                        break;
                    }
                }
            } else {
                if (itemArray[0].equals(propertyValue)) {
                    return itemArray[1];
                }
            }
        }
        return StringUtils.stripEnd(propertyString.toString(), separator);
    }

    //将excel的数据类型转为java数据类型
    @Override
    public String convertToJavaData(ReadCellData readCellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        String stringValue = readCellData.getStringValue();
        //获取字段属性中的注解
        Field field = excelContentProperty.getField();
        EasyExcel easyExcel = field.getAnnotation(EasyExcel.class);
        //获取注解中的枚举信息
        Class<? extends Enum> type = easyExcel.type();
        if (!type.getName().endsWith("None")) {
            //获取枚举类的方法名 “getEnum”就是自己编写的函数，Integer.class 指定入参类型
            Method codeOf = type.getMethod("getDesc", String.class);
            //反射执行方法，此方法得到的是一个枚举实例（具体得到什么，结合自身项目）
            Object invoke = codeOf.invoke(type, stringValue);
            //枚举实例调用getEnumDesc方法，得到name的值
            Method getName = invoke.getClass().getMethod("getEnum");
            String name = String.valueOf(getName.invoke(invoke));
            //将转换的值进行返回
            return name;
        } else if (StringUtils.isNotEmpty(easyExcel.readConverterExp())) {  // 解析配置的字符串
            return convertByExp2(stringValue, easyExcel.readConverterExp(), easyExcel.separator());
        }
        return stringValue;
    }

    public static String convertByExp2(String propertyValue, String converterExp, String separator) {
        StringBuilder propertyString = new StringBuilder();
        String[] convertSource = converterExp.split(",");
        for (String item : convertSource) {
            String[] itemArray = item.split("=");
            if (StringUtils.containsAny(propertyValue, separator)) {
                for (String value : propertyValue.split(separator)) {
                    if (itemArray[1].equals(value)) {
                        propertyString.append(itemArray[0] + separator);
                        break;
                    }
                }
            } else {
                if (itemArray[1].equals(propertyValue)) {
                    return itemArray[0];
                }
            }
        }
        return StringUtils.stripEnd(propertyString.toString(), separator);
    }
}
